#pragma once

namespace wxx {
namespace com
{
	struct single_threaded
	{
		static unsigned long increment(unsigned long* p) throw()
		{
			return ++(*p);
		}

		static unsigned long decrement(unsigned long* p) throw()
		{
			return --(*p);
		}
	};

	struct multi_threaded
	{
		static long increment(long* p) throw()
		{
			return ::InterlockedIncrement(p);
		}

		static long decrement(long* p) throw()
		{
			return ::InterlockedDecrement(p);
		}
	};

	template<class ThreadModel>
	struct com_object : IUnknown
	{
		virtual unsigned long __stdcall AddRef()
		{
			return ThreadModel::increment(&m_refcount);
		}

		virtual unsigned long __stdcall Release()
		{
			long result = ThreadModel::decrement(&m_refcount);

			if (!m_refcount)
			{
				delete this;
			}

			return result;
		}

	private:
		long m_refcount;
	};
}}